use super::Runtime;
use crate::Error;

#[derive(Clone)]
pub(crate) struct Config {
    pub(crate) qlen: usize,
    pub(crate) nth: usize,
    pub(crate) id: u8,
    pub(crate) name: &'static str,
}

pub struct Builder {
    conf: Config,
}

impl Config {
    pub(crate) const fn new(id: u8) -> Self {
        Self {
            qlen: 0,
            nth: 0,
            id,
            name: "",
        }
    }
}

impl Builder {
    /// 参数id代表运行时的id
    pub const fn new() -> Self {
        Self {
            conf: Config::new(0),
        }
    }

    /// 运行时的ID, 缺省运行时的ID为0. 每个id对应一个独立的运行时实例, 和Attr::id保持一致.
    pub fn id(&mut self, id: u8) -> &mut Self {
        self.conf.id = id;
        self
    }

    /// 运行时的名字，是此运行时所有工作线程名字的前缀
    pub fn name(&mut self, name: &'static str) -> &mut Self {
        self.conf.name = name;
        self
    }

    /// 设置运行时内部mpsc队列的大小，这个队列并非用于task调度，仅用于控制消息.
    /// 任务调度的队列没有大小限制
    pub fn qlen(&mut self, len: usize) -> &mut Self {
        self.conf.qlen = len;
        self
    }

    /// 设置运行时的工作线程的数量，缺省为当前CPU核的数量.
    pub fn nth(&mut self, nth: usize) -> &mut Self {
        self.conf.nth = nth;
        self
    }

    /// 启动运行时，如果id对应的运行时已经启动，则会返回Err.
    pub fn build(&mut self) -> Result<(), Error> {
        Runtime::active(Runtime::new(&self.conf)?)
    }

    /// 强制启动运行时，如果id对应的运行时已经启动，则会强制退出然后重启.不能在worker线程中调用重启本Runtime实例.
    /// # Safety
    /// 使用人员保证不能出现并发调用.
    pub unsafe fn rebuild(&mut self) -> Result<(), Error> {
        Runtime::reactive(Runtime::new(&self.conf)?)
    }
}
